#include<disp_manager.h>


static PDispOpr g_ptDevicehead = NULL;
static PDispOpr g_ptDispDefault = NULL;
static DispBuffer g_tDispBuffer;
static unsigned int g_linewidth;
static unsigned int g_pixelwidth;


void RegisterDisplay(PDispOpr ptDispOpr)
{
   ptDispOpr->ptNext = g_ptDevicehead;
   g_ptDevicehead = ptDispOpr;
}

void DisplaySystemRegister(void)
{
	extern void FrameBufferRegister(void);
	FrameBufferRegister();
	//extern void WebRegister(void);
	//WebRegister();etc
}

int SelectDefaultDisplay(char* name)
{
	PDispOpr pTemp = g_ptDevicehead;
	while(pTemp)
	{
		if(strcmp(name,pTemp->name) == 0)
		{
			g_ptDispDefault = pTemp;
			return 0;
		}
		pTemp = pTemp->ptNext;
	}
	return -1;
}

int InitDefaultDisplay(void)
{
	int ret;
	
	ret = g_ptDispDefault->DeviceInit();
	if(ret)
	{
		printf("DeviceInit err\n");
		return -1;
	}

	ret = g_ptDispDefault->GetBuffer(&g_tDispBuffer);
	if(ret)
	{
		printf("ptDispBuffer err\n");
		return -1;
	}
	
	g_linewidth = g_tDispBuffer.iXres * g_tDispBuffer.iBpp / 8;
	g_pixelwidth = g_tDispBuffer.iBpp / 8;
	
	return 0;
}

int PutPixel(int x, int y, unsigned int color)
{
	//unsigned int line_width = g_tDispBuffer.iXres * g_tDispBuffer.iBpp / 8;
	//unsigned int pixel_width = g_tDispBuffer.iBpp / 8;//可以先算好，节约时间
	
	unsigned char *pen_8 = (unsigned char *)g_tDispBuffer.buffer + y*g_linewidth + x*g_pixelwidth;
	unsigned short *pen_16;	
	unsigned int *pen_32;	
	
	unsigned int red, green, blue;	

	pen_16 = (unsigned short *)pen_8;
	pen_32 = (unsigned int *)pen_8;

	switch (g_tDispBuffer.iBpp)
	{
		case 8:
		{
			*pen_8 = color;
			break;
		}
		case 16:
		{
			/* 565 */
			red   = (color >> 16) & 0xff;
			green = (color >> 8) & 0xff;
			blue  = (color >> 0) & 0xff;
			color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
			*pen_16 = color;
			break;
		}
		case 32:
		{
			*pen_32 = color;
			break;
		}
		default:
		{
			printf("can't surport %dbpp\n", g_tDispBuffer.iBpp);
			return -1;//
			break;
		}
	}
	
	return 0;
}

void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor)
{
    int i, j, p, q;
	int x = ptFontBitMap->tRegion.iLeftUpX;
	int y = ptFontBitMap->tRegion.iLeftUpY;
    int x_max = x + ptFontBitMap->tRegion.iWidth;
    int y_max = y + ptFontBitMap->tRegion.iHeight;
	int width = ptFontBitMap->tRegion.iWidth;
	unsigned char *buffer = ptFontBitMap->pucBuffer;

    //printf("x = %d, y = %d\n", x, y);

    for ( j = y, q = 0; j < y_max; j++, q++ )
    {
        for ( i = x, p = 0; i < x_max; i++, p++ )
        {
            if ( i < 0      || j < 0       ||
                i >= g_tDispBuffer.iXres || j >= g_tDispBuffer.iYres )
            continue;

            //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
            if (buffer[q * width + p])
	            PutPixel(i, j, dwColor);
        }
    }
	
}


void DrawRegion(PRegion ptRegion, unsigned int dwColor)
{
	int x = ptRegion->iLeftUpX;
	int y = ptRegion->iLeftUpY;
	int width = ptRegion->iWidth;
	int height = ptRegion->iHeight;
	int i;
	int j;
	
	for(i = x; i < x + width; i++)
	{
		for(j = y; j < y + height; j++)
		{
			PutPixel(i, j, dwColor);
		}

	}
	
}


void DrawTextInRegionCenter(char *name, PRegion ptRegion, unsigned int dwColor)
{
	FontBitMap tFontBitMap;
	int i = 0;
	RegionCartesian tRegionCar;
	int error;

	//计算字符串边框
	GetStringRegionCar(name, &tRegionCar);
	
	//计算origin
	tFontBitMap.iCurOriginX = ptRegion->iLeftUpX + (ptRegion->iWidth - tRegionCar.iWidth) / 2 - tRegionCar.iLeftUpX;
	tFontBitMap.iCurOriginY = ptRegion->iLeftUpY + (ptRegion->iHeight - tRegionCar.iHeight) / 2 + tRegionCar.iLeftUpY;
	
	while(name[i])
	{
		error = GetFontBitMap(name[i], &tFontBitMap);
		if (error)
		{
			printf("GetFontBitMap err\n");
			return;
		}
		
		DrawFontBitMap(&tFontBitMap, dwColor);
		
		
		tFontBitMap.iCurOriginX = tFontBitMap.iNextOriginX;
		tFontBitMap.iCurOriginY = tFontBitMap.iNextOriginY;
		i++;
	}

}


PDispBuffer GetDisplayBuffer(void)
{
   return &g_tDispBuffer;
}

int FlushDisplayRegion(PRegion ptRegion, PDispBuffer ptDispBuffer)
{
	return g_ptDispDefault->FlushRegion(ptRegion,ptDispBuffer);
}



